﻿/**
 * numberbox - jQuery jwwUI Copyright (c) 2013-2015 www.jeeww.com. All rights reserved. 
 * Licensed under the GPL or commercial licenses 
 */
(function($) {
	function numberboxField(target) {
		$(target).addClass("numberbox-f");
		var v = $("<input type=\"hidden\">").insertAfter(target);
		var name = $(target).attr("name");
		if (name) {
			v.attr("name", name);
			$(target).removeAttr("name").attr("numberboxName", name);
		}
		return v;
	}
	;
	function setNumberBoxOtherInfo(target) {
		var definations = $.data(target, "numberbox").definations;
		var fn = definations.onChange;
		definations.onChange = function() {
		};
		setValue(target, definations.parser.call(target, definations.value));
		definations.onChange = fn;
		definations.originalValue = getValue(target);
	}
	;
	function getValue(target) {
		return $.data(target, "numberbox").field.val();
	}
	;
	function setValue(target, value) {
		var numberbox = $.data(target, "numberbox");
		var definations = numberbox.definations;
		var oldValue = getValue(target);
		value = definations.parser.call(target, value);
		definations.value = value;
		numberbox.field.val(value);
		$(target).val(definations.formatter.call(target, value));
		if (oldValue != value) {
			definations.onChange.call(target, value, oldValue);
		}
	}
	;
	function bindEvent(target) {
		var definations = $.data(target, "numberbox").definations;
		$(target).unbind(".numberbox").bind(
		        "keypress.numberbox",
		        function(e) {
			        if (e.which == 45) {
				        if ($(this).val().indexOf("-") == -1) {
					        return true;
				        } else {
					        return false;
				        }
			        }
			        if (e.which == 46) {
				        if ($(this).val().indexOf(".") == -1) {
					        return true;
				        } else {
					        return false;
				        }
			        } else {
				        if ((e.which >= 48 && e.which <= 57 && e.ctrlKey == false && e.shiftKey == false)
				                || e.which == 0 || e.which == 8) {
					        return true;
				        } else {
					        if (e.ctrlKey == true && (e.which == 99 || e.which == 118)) {
						        return true;
					        } else {
						        return false;
					        }
				        }
			        }
		        }).bind("blur.numberbox", function() {
			setValue(target, $(this).val());
			$(this).val(definations.formatter.call(target, getValue(target)));
		}).bind("focus.numberbox", function() {
			var vv = getValue(target);
			if ($(this).val() != vv) {
				$(this).val(vv);
			}
		});
	}
	;
	function validateNumberBox(target) {
		if ($.fn.inputbox) {
			var definations = $.data(target, "numberbox").definations;
			$(target).inputbox(definations);
		}
	}
	;
	function enableOrDisable(target, flag) {
		var definations = $.data(target, "numberbox").definations;
		if (flag) {
			definations.disabled = true;
			$(target).attr("disabled", true);
		} else {
			definations.disabled = false;
			$(target).removeAttr("disabled");
		}
	}
	;
	$.fn.numberbox = function(definations, param) {
		if (typeof definations == "string") {
			var fun = $.fn.numberbox.methods[definations];
			if (fun) {
				return fun(this, param);
			} else {
				return this.inputbox(definations, param);
			}
		}
		definations = definations || {};
		return this.each(function() {
			var numberbox = $.data(this, "numberbox");
			if (numberbox) {
				$.extend(numberbox.definations, definations);
			} else {
				numberbox = $.data(this, "numberbox", {
				    definations : $.extend({}, $.fn.numberbox.defaults, $.fn.numberbox.parseDefinations(this), definations),
				    field : numberboxField(this) });
				$(this).removeAttr("disabled");
				$(this).css({ imeMode : "disabled" });
			}
			enableOrDisable(this, numberbox.definations.disabled);
			bindEvent(this);
			validateNumberBox(this);
			setNumberBoxOtherInfo(this);
		});
	};
	$.fn.numberbox.methods = { definations : function(jq) {
		return $.data(jq[0], "numberbox").definations;
	}, destroy : function(jq) {
		return jq.each(function() {
			$.data(this, "numberbox").field.remove();
			$(this).inputbox("destroy");
			$(this).remove();
		});
	}, disable : function(jq) {
		return jq.each(function() {
			enableOrDisable(this, true);
		});
	}, enable : function(jq) {
		return jq.each(function() {
			enableOrDisable(this, false);
		});
	}, fix : function(jq) {
		return jq.each(function() {
			setValue(this, $(this).val());
		});
	}, setValue : function(jq, _1d) {
		return jq.each(function() {
			setValue(this, _1d);
		});
	}, getValue : function(jq) {
		return getValue(jq[0]);
	}, clear : function(jq) {
		return jq.each(function() {
			var numberbox = $.data(this, "numberbox");
			numberbox.field.val("");
			$(this).val("");
		});
	}, reset : function(jq) {
		return jq.each(function() {
			var definations = $(this).numberbox("definations");
			$(this).numberbox("setValue", definations.originalValue);
		});
	} };
	$.fn.numberbox.parseDefinations = function(target) {
		var t = $(target);
		return $.extend({}, $.fn.inputbox.parseDefinations(target), $.parser.parseDefinations(target, [ "decimalSeparator",
		        "groupSeparator", "suffix", { min : "number", max : "number", precision : "number" } ]), {
		    prefix : (t.attr("prefix") ? t.attr("prefix") : undefined),
		    disabled : (t.attr("disabled") ? true : undefined), value : (t.val() || undefined) });
	};
	$.fn.numberbox.defaults = $.extend({}, $.fn.inputbox.defaults, { disabled : false, value : "", min : null,
	    max : null, precision : 0, decimalSeparator : ".", groupSeparator : "", prefix : "", suffix : "",
	    formatter : function(value) {
		    if (!value) {
			    return value;
		    }
		    value = value + "";
		    var definations = $(this).numberbox("definations");
		    var s1 = value, s2 = "";
		    var index = value.indexOf(".");
		    if (index >= 0) {
			    s1 = value.substring(0, index);
			    s2 = value.substring(index + 1, value.length);
		    }
		    if (definations.groupSeparator) {
			    var p = /(\d+)(\d{3})/;
			    while (p.test(s1)) {
				    s1 = s1.replace(p, "$1" + definations.groupSeparator + "$2");
			    }
		    }
		    if (s2) {
			    return definations.prefix + s1 + definations.decimalSeparator + s2 + definations.suffix;
		    } else {
			    return definations.prefix + s1 + definations.suffix;
		    }
	    }, parser : function(value) {
		    value = value + "";
		    var definations = $(this).numberbox("definations");
		    if (definations.groupSeparator) {
			    value = value.replace(new RegExp("\\" + definations.groupSeparator, "g"), "");
		    }
		    if (definations.decimalSeparator) {
			    value = value.replace(new RegExp("\\" + definations.decimalSeparator, "g"), ".");
		    }
		    if (definations.prefix) {
			    value = value.replace(new RegExp("\\" + $.trim(definations.prefix), "g"), "");
		    }
		    if (definations.suffix) {
			    value = value.replace(new RegExp("\\" + $.trim(definations.suffix), "g"), "");
		    }
		    value = value.replace(/\s/g, "");
		    var val = parseFloat(value).toFixed(definations.precision);
		    if (isNaN(val)) {
			    val = "";
		    } else {
			    if (typeof (definations.min) == "number" && val < definations.min) {
				    val = definations.min.toFixed(definations.precision);
			    } else {
				    if (typeof (definations.max) == "number" && val > definations.max) {
					    val = definations.max.toFixed(definations.precision);
				    }
			    }
		    }
		    return val;
	    }, onChange : function(newValue, oldValue) {
	    } });
})(jQuery);
